﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    public class Alien
    {
        public delegate void DieDelegate(Alien a);
        public event DieDelegate EventDie;

        Sprite spr = new Sprite();
        Sprite sprLive = new Sprite();
        public StateMachine stateMachine = new StateMachine();

        public Vector2 pos;
        public Vector2 direction;
        public float speed;
        public Vector2 size = new Vector2(32, 32);
        public Vector2 hitBox = new Vector2(32, 32);
        public float lifePoint = 10;
        public float initialLifePoint;
        public float hit = 0;

        public float freeze = 0;
        public float timeSinceFreeze = 0;

        public int colorIndex;
        public int score = 100;
        public bool collision = true;

        public bool IsFrozen() { return freeze == 1.0f; }
        public bool IsAlive() { return lifePoint > 0; }

        public Alien()
        {
            pos = new Vector2(200, 200);
            direction = new Vector2(0, 1);
            speed = 150;
            spr.origin = new Vector2(0.5f, 0.5f);
        }

        public void Draw(SpriteBatch sb)
        {
            if (IsAlive() == false)
                return;

            spr.size = size;
            spr.pos = pos;
            spr.color = Palette.alienColors[colorIndex];
            spr.color = Color.Lerp(spr.color, Color.PowderBlue, freeze);
            spr.color = Color.Lerp(spr.color, Color.White, hit);
            spr.Draw(sb);

            sprLive.size = new Vector2(size.X * (lifePoint / initialLifePoint) , 3);
            sprLive.pos = pos - size * spr.origin;
            sprLive.color = Color.Yellow;
            sprLive.Draw(sb);
        }

        public virtual void Update(Timer t)
        {
            if (initialLifePoint == 0)
                initialLifePoint = lifePoint;

            stateMachine.Update(t);
            UpdatePosition(t);
            UpdateShootingStatus(t);
            UpdateHitStatus(t);

            if (freeze > 0)
            {
                timeSinceFreeze += t.Delta;
                float d = timeSinceFreeze - 5.0f;
                if (d < 0)
                    d = 0;
                freeze -= d * 0.5f;
                if (freeze < 0)
                {
                    timeSinceFreeze = 0;
                    freeze = 0;
                }
            }
        }

        protected virtual void UpdateShootingStatus(Timer t)
        {

        }

        protected virtual void UpdateHitStatus(Timer t)
        {
            if (hit > 0)
            {
                hit -= t.Delta * 1.0f;
            }
        }

        protected virtual void UpdatePosition(Timer t)
        {
            float nfreeze = 1.0f - freeze;
            float localSpeed = speed * (1 - hit * 0.5f) * nfreeze;
            pos += direction * localSpeed * t.Delta;
        }

        public void Hit(float damage)
        {
            hit = 1;
            lifePoint -= damage;
            if (IsAlive() == false)
            {
                OnEventDie();
            }
        }


        public virtual void OnEventHit(Bullet b)
        {
            Hit(b.damage);
        }

        public virtual void OnEventHitByLazor()
        {
            hit = 1;
            if (IsFrozen())
            {
                OnEventInstantKill();
            }
            else
            {
                Hit(3.0f);
            }
        }

        public virtual void OnEventInstantKill()
        {
            Hit(-lifePoint);

            for (float f = 0; f < 360; f += 8)
            {
                Bullet b = new Bullet();
                b.pos = pos;
                b.radius = size.X;
                b.size = size * 0.33f;
                b.color0 = Color.PowderBlue;
                b.color1 = Color.PowderBlue;
                Vector3 dir = Vector3.Transform(new Vector3(0, 1, 0), Matrix.CreateRotationZ(MathHelper.ToRadians(f)));
                b.dir = new Vector2(dir.X, dir.Y);
                b.speed = 1000;
                b.damage = 100;
                Game1.instance.bulletManager.bullets.Add(b);
            }
        }

        protected virtual void OnEventDie()
        {
            Game1.instance.score += score;
            OnEventExplode();
            
            if (EventDie != null)
                EventDie(this);
        }

        protected virtual void OnEventExplode()
        {
            Game1.instance.explosionManager.AddExplosion(pos);
        }

        public void OnEventShoot(Vector2 error)
        {
            Bullet b = Bullet.CreateFatBullet();
            b.pos = pos;
            b.dir = Vector2.Normalize(Game1.instance.plane.pos - pos + error);
            b.owner = this;
            Game1.instance.alienBulletManager.bullets.Add(b);
        }

        public Rectangle ComputeRect()
        {
            int x = (int)(pos.X - size.X * 0.5f);
            int y = (int)(pos.Y - size.Y * 0.5f);
            int w = (int)size.X;
            int h = (int)size.Y;
            return new Rectangle(x, y, w, h);
        }

        public void OnEventFreeze()
        {
            freeze += 0.01f;
            if (freeze > 1.0f)
            {
                freeze = 1.0f;
            }
        }

    }
}
